﻿using System;
using System.Web.Mvc;
using NUnit.Framework;
using WeBlog.Controllers;
using WeBlog.DataContext;
using WeBlog.Interfaces;
using WeBlog.Models;
using WeBlog.Repositories;
using WeBlog.Services;
using WeBlog.Tests.Helpers;
using WeBlog.Tests.Mocks;
using System.Collections.Generic;

namespace WeBlog.Tests.Controllers {
	[TestFixture]
	public class AdminControllerTests {

        private IUnitOfWork _unitOfWork;
        private User _admin = new User { UserId = 100, Email = "admin@weblog.com", FirstName = "admin", LastName = "admin", Password = "admin", Activated = true, RoleFlag = RoleValues.Admin };
        private MockPrincipal _adminPrincipal = new MockPrincipal(new MockIdentity("admin@weblog.com"), new[] { Role.Admin });

		[SetUp]
		public void Setup() 
        {
            _unitOfWork = new InMemoryUnitOfWork();
            var repository = new UserRepository(_unitOfWork);
            repository.Add(_admin);
		}

		[Test]
		public void ExtractSlug_Returns_Proper_Title()         
        {
            //Arrange
            var controller = new AdminController(_unitOfWork);
			const string title = "I like toast";			

            //Act
			string slug = controller.ExtractSlug(title);

            //Assert
			Assert.AreEqual("I-like-toast", slug);
		}

		[Test]
		public void Settings_Returns_Valid_Model() {
            //Arrange
            var controller = new AdminController(_unitOfWork);

            //Act
			var result = controller.Index() as ViewResult;

            //Assert
            Assert.IsInstanceOf(typeof(SettingsViewModel), result.ViewData.Model);
		}

        [Test]
        public void Index_Action_Should_Return_Proper_View()
        {
            //Arrange
            var controller = new AdminController(_unitOfWork);

            //Act
            var result = controller.Index() as ViewResult;

            //Assert
            Assert.IsNullOrEmpty(result.ViewName);
        }

        [Test]
        public void Settings_Action_Should_Succeed_And_Return_Proper_Model_When_Input_Is_Valid()
        {
            //Arrange
            var formValues = new Dictionary<string, string>();
            formValues.Add("Settings.Name", "MyBlog");

            var controller = new AdminController(_unitOfWork);
            controller.CurrentUser = _admin;
            controller.SetFakeControllerContext(_adminPrincipal, _admin);
            controller.ValueProvider = MvcMockHelpers.SetupValueProvider(formValues);

            //Act
            var result = controller.Index(new FormCollection()) as ViewResult;

            //Assert            
            Assert.IsInstanceOf(typeof(SettingsViewModel), result.ViewData.Model);
            Assert.IsTrue(result.ViewData.ModelState.IsValid); 
            Assert.AreEqual("MyBlog", SiteManager.CurrentConfiguration.Name);            
        }

        [Test]
        public void Settings_Action_Should_Fail_When_Input_Is_Invalid()
        {
            //Arrange
            var formValues = new Dictionary<string, string>();
            formValues.Add("Settings.AreCommentsEnabled", "hello");

            var controller = new AdminController(_unitOfWork);
            controller.CurrentUser = _admin;
            controller.SetFakeControllerContext(_adminPrincipal, _admin);
            controller.ValueProvider = MvcMockHelpers.SetupValueProvider(formValues);

            //Act
            var result = controller.Index(new FormCollection()) as ViewResult;

            //Assert
            Assert.IsInstanceOf(typeof(SettingsViewModel), result.ViewData.Model);
            Assert.IsFalse(result.ViewData.ModelState.IsValid);
        }
	}
}
